package org.kgduyjj.toolkit.util;

import java.util.Map;

import lombok.extern.slf4j.Slf4j;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Http请求工具类
 * 
 * <p>
 * 工具依赖OKHTTP
 *
 * @author Kgduyjj
 */
@Slf4j
public class HttpUtil {

    public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");
    public static final MediaType MEDIA_TYPE_XML = MediaType.parse("application/xml; charset=utf-8");

    /**
     * GET
     *
     * @param url     请求的url
     * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
     * @return String
     */
    public static String get(String url, Map<String, Object> queries) {
        return get(url, null, queries);
    }

    /**
     * GET
     *
     * @param url     请求的url
     * @param header  请求头
     * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
     * @return String
     */
    public static String get(String url, Map<String, String> header, Map<String, Object> queries) {
        StringBuffer requestContent = new StringBuffer(url);
        if (queries != null && queries.keySet().size() > 0) {
            queries.forEach((key, value) -> {
                // requestContent.append("?clientId=blade");
                // 解决首个参数的格式问题
                boolean first = true;
                if (first) {
                    requestContent.append("?").append(key).append("=").append(value);
                    first = false;
                }
                requestContent.append("&").append(key).append("=").append(value);
            });
        }

        Request.Builder builder = new Request.Builder();

        if (header != null && header.keySet().size() > 0) {
            header.forEach(builder::addHeader);
        }

        Request request = builder.url(requestContent.toString()).build();
        return getBody(request);
    }

    /**
     * POST
     *
     * @param url    请求的url
     * @param params post form 提交的参数
     * @return String
     */
    public static String post(String url, Map<String, String> params) {
        return post(url, null, params);
    }

    /**
     * POST
     *
     * @param url    请求的url
     * @param header 请求头
     * @param params post form 提交的参数
     * @return String
     */
    public static String post(String url, Map<String, String> header, Map<String, String> params) {
        FormBody.Builder formBuilder = new FormBody.Builder();
        // .add("clientId", "blade");
        // 添加参数
        if (params != null && params.keySet().size() > 0) {
            params.forEach(formBuilder::add);
        }

        Request.Builder builder = new Request.Builder();

        if (header != null && header.keySet().size() > 0) {
            header.forEach(builder::addHeader);
        }

        Request request = builder.url(url).post(formBuilder.build()).build();
        return getBody(request);
    }

    /**
     * POST请求发送JSON数据
     *
     * @param url  请求的url
     * @param json 请求的json串
     * @return String
     */
    public static String postJson(String url, String json) {
        return postJson(url, null, json);
    }

    /**
     * POST请求发送JSON数据
     * 
     * @param url    请求的url
     * @param header 请求头
     * @param json   请求的json串
     * @return String
     */
    public static String postJson(String url, Map<String, String> header, String json) {
        return postContent(url, header, json, MEDIA_TYPE_JSON);
    }

    /**
     * POST请求发送xml数据
     *
     * @param url 请求的url
     * @param xml 请求的xml串
     * @return String
     */
    public static String postXml(String url, String xml) {
        return postXml(url, null, xml);
    }

    /**
     * POST请求发送xml数据
     *
     * @param url    请求的url
     * @param header 请求头
     * @param xml    请求的xml串
     * @return String
     */
    public static String postXml(String url, Map<String, String> header, String xml) {
        return postContent(url, header, xml, MEDIA_TYPE_XML);
    }

    /**
     * 发送POST请求
     *
     * @param url       请求的url
     * @param header    请求头
     * @param content   请求内容
     * @param mediaType 请求类型
     * @return String
     */
    public static String postContent(String url, Map<String, String> header, String content, MediaType mediaType) {
        RequestBody requestBody = RequestBody.create(mediaType, content);
        Request.Builder builder = new Request.Builder();

        if (header != null && header.keySet().size() > 0) {
            header.forEach(builder::addHeader);
        }
        Request request = builder.url(url).post(requestBody).build();
        return getBody(request);
    }

    /**
     * 获取body
     *
     * @param request request
     * @return String
     */
    private static String getBody(Request request) {
        String responseBody = "";
        Response response = null;
        try {
            OkHttpClient okHttpClient = new OkHttpClient();
            response = okHttpClient.newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error("okhttp3 post error >> ex = {}", e.getMessage());
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return responseBody;
    }

}
